package forum.client.controllerlayer;

import forum.client.ui.ForumViewWorker;
import forum.client.ui.events.ForumTreeErrorEvent;
import forum.client.ui.events.ForumTreeRefreshEvent;
import java.awt.Component;
import java.util.Date;
import java.util.Observable;

import forum.server.domain.Gender;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;

/**
 * This abstract class is in charge of the communication between
 * the UI layer and the Controller layer.
 *
 * @author Tomer Heber
 */
public abstract class ControllerHandler extends Observable {

	@Override
	public synchronized void notifyObservers(Object o) {
		setChanged();
		super.notifyObservers(o);
	}

	/**
	 * @return and encoded view of the forum.<br>
	 * An example of such an encoding can be some sort of XML string.<br>
	 * For example:<br>
	 * <message> id: user: sdfsdf content: fsdfsd
	 * 		<message>
	 *			...
	 *		</message>
	 *		<message>
	 *			...
  	 *		</message>
	 * </message>
	 */
	public abstract String[] getForumView();

	/**
	 * Tries to modify a message.
	 *
	 * @param id The id of the message to be modified.
	 * @param newContent The new content of the message.
	 */
	public abstract String[] modifyMessage(long id, String newContent, Component comp);

	/**
	 * Adds a reply message.
	 *
	 * @param id The id of the message to which we reply.
	 * @param string The content of the new message.
	 */
	public abstract String[] addReplyToMessage(long id, String string, Component comp);

	/**
	 * Deletes recursively the message id and all his sons.
	 *
	 * @param id The id of the message to delete.
	 */
	public abstract String[] deleteMessage(long id, Component comp);

	/**
	 * Adds a new message to the forum.
	 */
	public abstract String[] addNewMessage(String header, String body,Component comp);
	
	/**
	 * gets the users that can be demoted - the moderators.
	 * @return all the moderators.
	 */
	public abstract String[] getUsersToDemote();
	
	/**
	 * gets the users that can be promoted - the logged in users.
	 * @return all the LoggedInUsers that are not moderators or admin.
	 */
	public abstract String[] getUsersToPromote();
	
	/**
	 *
	 * @return all the users in the system.
	 */
	public abstract String[] getAllUsers();
	
	/**
	 * This function demotes users.
	 * @param users the users to demote.
	 */
	public abstract void demoteUsers(String[] users);
	
	/**
	 * this function promotes the users.
	 * @param users the users to promote.
	 */
	public abstract void promoteUsers(String[] users);
	
	/**
	 * 
	 * @param comp
	 * @param user
	 * @param pass
	 */
	public abstract String[] login(Component comp, String user, String pass) ;

	/**
	 * 
	 * @param comp
	 */
    public abstract String[] logoff(boolean exitStatus) ;

    /**
     * 
     * @param myself
     * @param username
     * @param password
     * @param firstName
     * @param lastName
     * @param email
     * @param gender
     * @param city
     * @param birthday
     */
    public abstract String[] register(Component myself, String username,
    		String password, String firstName, String lastName, String email, 
    		Gender gender, String city, Date birthday);
    
	/**
	 * 
	 * @param username
	 * @param from
	 * @param to
	 * @param comp
	 */
    public abstract String[] searchByAuthor(String username, int from, int to, Component comp);
    
    /**
     * 
     * @param content
     * @param from
     * @param to
     * @param comp
     */
    public abstract String[] searchByContent(String content, int from, int to, Component comp);
    
    /**
     * Used to diaplay status.
     * @return
     */
    public abstract String[] getConnectedUsers();

    /**
     * Used for greeting current user.
     * @return
     */
    public abstract String getLoggedInUser();

    public abstract String[] getOneSearchView(int postID);

    public void refreshForum(ExecutorService pool){
        ForumViewWorker fvw = new ForumViewWorker();
        pool.execute(fvw);
        try{
            String[] result = (String[]) fvw.get();
            if (result[0].equals("succ")){
                notifyObservers(new ForumTreeRefreshEvent(result[1]));
            }
        } catch (InterruptedException ex) {}
        catch (ExecutionException ex) {
            notifyObservers(new ForumTreeErrorEvent("Execution exception."));
        }

    }
}
